package main

import (
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/beevik/etree"
	"github.com/use-go/onvif"
	"github.com/use-go/onvif/media"
	"github.com/use-go/onvif/ptz"
	xsdonvif "github.com/use-go/onvif/xsd/onvif"
)

const (
	// 一般云台是托管给可见光的, 例如海康, 默认会提供一个web管理后台
	Addr     string = "10.1.6.94"
	Username string = "admin"
	Password string = "admin12345"
)

var onvifTokens = make(map[int]string)
var videoTokens = make(map[int]string)

func main() {
	dev, err := onvif.NewDevice(onvif.DeviceParams{
		Xaddr:      Addr,
		Username:   Username,
		Password:   Password,
		HttpClient: &http.Client{},
	})
	if err != nil {
		return
	}
	// 登录
	// dev.Authenticate(Username, Password)

	// 获取profiles 查询onvifTokens
	profiles := media.GetProfiles{}
	profilesRes, err := dev.CallMethod(profiles)
	if err != nil {
		panic(err)
	}

	b, err := ioutil.ReadAll(profilesRes.Body)
	if err != nil {
		panic(err)
		// return
	}

	doc := etree.NewDocument()
	doc.ReadFromBytes(b)
	root := doc.SelectElement("Envelope")
	if root == nil {
		return
	}
	token := root.FindElements("./Body/GetProfilesResponse/Profiles")
	if token == nil {
		return
	}

	for k, res := range token {

		_token := res.SelectAttr("token").Value
		onvifTokens[k] = _token

		// video token
		v := res.FindElement("./VideoSourceConfiguration/SourceToken")
		if v != nil {
			videoTokens[k] = v.Text()
		}

	}

	// 云台上下左右变倍控制
	// 参考官网文档: https://www.onvif.org/profiles/specifications/
	var _x = 0.1    // p值控制
	var _y = 0.1    // t值控制
	var _zoom = 0.1 // z值控制
	// ptzControl := ptz.ContinuousMove{
	// 	ProfileToken: xsdonvif.ReferenceToken(onvifTokens[0]),

	// 	Velocity: xsdonvif.PTZSpeed{
	// 		PanTilt: xsdonvif.Vector2D{
	// 			X: _x,
	// 			Y: _y,
	// 		},
	// 		Zoom: xsdonvif.Vector1D{
	// 			X: _zoom,
	// 		},
	// 	},
	// 	Timeout: "PT10S",
	// }
	move := ptz.RelativeMove{
		ProfileToken: xsdonvif.ReferenceToken(onvifTokens[0]),

		Speed: xsdonvif.PTZSpeed{
			PanTilt: xsdonvif.Vector2D{
				X: _x,
				Y: _y,
			},
			Zoom: xsdonvif.Vector1D{
				X: _zoom,
			},
		},
	}

	res, err := dev.CallMethod(move)
	if err != nil {
		return
	}
	b, err = ioutil.ReadAll(res.Body)
	if err != nil {
		return
	}
	log.Println(string(b))
	// 记得调用停止移动接口
	time.Sleep(2 * time.Second)

	stop := ptz.Stop{
		ProfileToken: xsdonvif.ReferenceToken(onvifTokens[0]),
		PanTilt:      true,
		Zoom:         true,
	}

	res, err = dev.CallMethod(stop)
	if err != nil {
		return
	}
	b, err = ioutil.ReadAll(res.Body)
	if err != nil {
		return
	}
	log.Println(string(b))

	return
}
